/*
 *	(GNU GPL) kobey
 *	这是一个非常简单的测试用例，只是用来探测在编写文章的时候，做一些理论上的实践测试
 *	1,malloc内存分配器分配的内存可能大于所希望分配的内存
 *		1）涉及到malloc内部数据结构实现字节对齐的问题，比如8字节对齐
 *		2）类似缓存技术的实现，避免频繁系统调用的CPU耗损	
 *	2, mallopt动态调整malloc分配的内存情况
 *		https://blog.csdn.net/u013920085/article/details/52847464
 *
 *	3，实验中，我使用gcc 7.5的版本，发现malloc的实现已经与一些书本的理论知识有所差异
 *		所以，一切还是以实际为主呀
 *
 *	4，brk与mmap的使用区别，可以设置一个阀值，默认128KB，
 *		小于128KB那么这个堆空间就算释放，也会保留缓存
 *		大于128KB就会触发一个brk，通知内核释放空闲的这个缓存，回收资源
 *		也就是说，在一些内存申请很小的情况下所谓的释放，更不如说是让它空闲
 *
 *	5，内存泄露和内存空洞
 *		1）内存泄露是程序运行随着时间增长，内存申请与分配不成比例，内存使用量呈现
 *			震荡扩大
 *		2）内存空洞是程序堆空间使用brk申请后，移动了堆顶指针brk，但是在释放的时候
 *			因为申请内存地址都带有一定的随机性，后面申请的内存不一定就是堆顶，
 *			所以严格上做到内存从堆顶释放是不可能的，那么当我们释放堆顶一下，
 *			实际上当进程释放掉内存后，系统还是无法回收进程所释放的内存，就跟进程
 *			依然在使用一样，这种现象就是内存空洞。
 *	6，怎么解决内存空洞？
 *		1）使用对系统调用更深层次的mmap，用性能替换空间
 *		2）使用其他内存管理机制
 *
 *		备注：有书籍论述，经过大量的内存优化过程发现，堆中更多的是内存碎片而不是内存空洞，
 *			当然空洞也可以说是内存碎片的一种。所以我们在使用中，可以知道这个概念，
 *			然后就按照glibc中的安全使用吧
 * 	
 *
 *	7，malloc与堆的总结
 *		我曾经面试遇到一个问题，问我了解malloc吗？
 *		现在也许我可以这样回答：
 *
 *		malloc是glibc封装好brk、mmap等系统调用后的对进程堆空间内存分配的一个接口。
 *		它的实现原理分别有：
 *		1）小块内存申请，这个小块的数值是可以通过mallopt动态调整，最后调用的系统调用是
 *			brk，但是请注意，并不一定会移动堆顶的指针brk，可能从原来已经释放的但是
 *			系统没有回收的空闲内存中分配对象，这个要看情况而论。
 *			如果再细说，也可以，我们这brk怎么分配内存，怎么释放内存
 *			比如，如果当前有适合大小的空闲内存，那么就分配，然后没有
 *			那么就移动堆顶指针，获取更大的内存空间。
 *			这个释放，因为申请的内存是动态随机的，所以我们无法确定堆顶指针当前的具体
 *			数值，所以这个释放可以理解为只是当前进程释放申请的内存，然后系统还没有回收，
 *			那么这个情况就可以理解为，存在很多内存碎片的问题，如果大于这个阀值才会
 *			触发系统回收，还有一种内存空洞的情况，就是释放掉堆顶指针下面的内存。
 *		2）大块内存的申请使用mmap系统调用
 *			从堆空间中，找一个虚拟地址直接分配，然后使用munmap释放，不存在碎片问题
 *			只要释放，那么系统就会回收，缺点就是系统调用嵌入太深，效率比较低。
 *	
 *
 *
 *
 *
 * */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
//	mallopt(M_MXFAST, 0);
	printf("text1: malloc\n");
	char *p = (char *)malloc(10);
	char *p0 = (char *)malloc(10);
	printf("malloc p address = %p\n", p);
//	strcpy(p, "Hello world!");
//	printf("%s\n", p);
	free(p);
	free(p0);
	p = NULL;
	p0 = NULL;
	

	printf("\n\n");
	printf("text2: mallopt\n");
	char *p1 = (char *)malloc(10);
	printf("malloc p1 address = %p\n", p1);
	free(p1);
	p1 = NULL;
	/*使用pause暂停进程，观察cat /proc/pid/maps中各个段的内存分布*/
	pause();

	return 0;
}

